

// class {} 其实就相当于一个壳子，
// 创建了一个独立作用域
// class Test {
//   // constructor 就相当于function(){}
//   // 构造器 -> Test()
//   constructor (a, b) {
//     this.a = a;
//     this.b = b;
//   }
//   // 一些方法
//   // static
//   // get
//   // set
//   // Test.prototype.add = function(){}
//   add(){}
// }


// constructor 构造函数
// function Test2(a, b) {
//   this.a = a;
//   this.b = b;
// }
// // 扩展构造函数的原型属性
// Test2.prototype.add = function() {
//   return this.a + this.b;
// }
// const t = new Test2(1, 2);
// console.log(t);


// ;(function (window) {
//   function Test(a, b) {
//     this.a = a;
//     this.b = b;
//   }

//   Test.prototype.add = function() {
//     return this.a + this.b;
//   }

//   window.Test = Test
// })(window)

// const test = new Test(1, 2);
// console.log(test);






/**
 * new 的过程
 * 1. 创建构造函数           function C (){}
 * 2. 实例化构造函数         new C()
 * 3. 接收构造函数中的返回值  var c = new C()
 * 
 * 实例化过程
 * 1. 产生一个this指向 -> {}(一个空对象)
 * 2. 当 this.a / this.b 时，会往空对象里添加
 *    {
 *      a: a,
 *      b: b,
 *      __proto__: C.prototype => {
 *                  constructor -> C
 *                  add: fn
 *                }
 *    }
 * 
 */



// 实现new 关键字
// var test = new Test(1, 2) => myNew(Test, 1, 2)

function myNew() {
  // 拿到第一个参数作为构造器
  var constructor = [].shift.call(arguments),
      _this = {};

  _this.__proto__ = constructor.prototype;
  
  // 改变 constructor 的this指向
  var res = constructor.apply(_this, arguments);

  // return _this; // 直接返回 _this 会不完整
  // 看这个执行的结果是否是 object(而不是判断实例化之后的结果)
  return typeof res === 'object' ? res : _this;
}


;(function (window) {
  function Test(a, b) {
    this.a = a;
    this.b = b;

    // return {
    //   c: 3,
    //   d: 4
    // }
  }

  Test.prototype.add = function() {
    return this.a + this.b;
  }

  window.Test = Test;
})(window);

var test = new Test(1, 2);
var test2 = myNew(Test, 1, 2);

console.log(test);
console.log(test2);







